﻿using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using NPOI.SS.Formula.Functions;
using Serilog;
using Serilog.Core;
using Serilog.Parsing;
using SimpleTool.Base;
using SimpleTool.SerialTool.SerialControl;
using SimpleTool.Server;
using SimpleTool.TransformComponent;
using SixLabors.ImageSharp;

namespace SimpleTool.ActivityUnit.EchoControl
{
    /// <summary>
    /// RegexpTestTool.xaml 的交互逻辑
    /// </summary>
    public partial class RegexpTestTool : EnjoyWindow
    {
        private RegexpViewModel? viewmodel = null;

        public class InfoPakage
        {
            public string content = string.Empty;

            public string regexp = string.Empty;
        }

        public RegexpTestTool(InfoPakage Ifpakage)
        {
            InitializeComponent();

            viewmodel = new (Ifpakage.content, Ifpakage.regexp);

            DataContext = viewmodel;

            Owner = Application.Current.MainWindow;

            WindowStartupLocation = WindowStartupLocation.CenterOwner;

            Loaded += CompleteLoaded;
            Unloaded += DistoryLoad;
        }

        public void CompleteLoaded(object sender, RoutedEventArgs e)
        {
            viewmodel?.Match();
            Loaded -= CompleteLoaded;
        }

        public void DistoryLoad(object sender, RoutedEventArgs e)
        {
            viewmodel = null;
            Unloaded -= DistoryLoad;
        }
    }

    public class RegexpViewModel : Notify
    {
        private readonly ILogger Logger = Serilog.Log.ForContext<SerialViewModel>();

        private string _content = string.Empty;

        private string _regexp = string.Empty;

        private string _regexpmc = "结果在这里展示";

        private string _clipboard = string.Empty;

        private ICommand? _Cmdregexp = null;

        private ICommand? _Cmdcptclipboard = null;

        private ICommand? _Cmdgetclipboard = null;

        private RegexpDescribe? Model = null;

        public string content
        {
            set
            {
                _content = value;
                propertyChangeSend(nameof(content));
            }
            get
            {
                return _content;
            }
        }

        public string regexp
        {
            set
            {
                _regexp = value;
                propertyChangeSend(nameof(regexp));
            }
            get
            {
                return _regexp;
            }
        }

        public string regexpmc
        {
            set
            {
                _regexpmc = value;
                propertyChangeSend(nameof(regexpmc));
            }
            get
            {
                return _regexpmc;
            }
        }

        public string clipboard
        {
            set
            {
                _clipboard = value;
                propertyChangeSend(nameof(clipboard));
            }
            get
            {
                return _clipboard;
            }
        }

        public RegexpDescribe HoldModel
        {
            set
            {
                Model = value;
                propertyChangeSend(nameof(HoldModel));
            }
            get
            {
                Model ??= new ();
                return Model;
            }
        }

        public ICommand Cmdregexp
        {
            set
            {
                _Cmdregexp = value;
            }
            get
            {
                _Cmdregexp ??= new EasyCommand((param) =>
                {
                    if (param is not null and string _reg)
                    {
                        regexp = _reg;
                        Match(regexp);
                    }
                }, () => true);
                return _Cmdregexp;
            }
        }

        public ICommand Cmdcptclipboard
        {
            set
            {
                _Cmdcptclipboard = value;
            }
            get
            {
                _Cmdcptclipboard ??= new EasyCommand((param) =>
                {
                    try
                    {
                        Clipboard.SetText(regexp);
                        clipboard = "已复制至剪贴板";
                    }
                    catch (Exception error)
                    {
                        clipboard = $"复制失败: {error.Message}";
                    }
                    finally
                    {
                        Task.Delay(2000).ContinueWith((task) =>
                        {
                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                clipboard = string.Empty;
                            });
                        });
                    }
                }, () => true);
                return _Cmdcptclipboard;
            }
        }

        public ICommand Cmdgetclipboard
        {
            set
            {
                _Cmdgetclipboard = value;
            }
            get
            {
                _Cmdgetclipboard ??= new EasyCommand((param) =>
                {
                    Application.Current.Dispatcher.InvokeAsync(() =>
                    {
                        content = Clipboard.GetText();
                        Match(regexp);
                    });
                }, () => true);
                return _Cmdgetclipboard;
            }
        }

        public RegexpViewModel(string _content, string _regexpstr)
        {

            content = _content.Replace("\r", "").Replace("\r", "");

            regexp = _regexpstr;
        }

        public void Match(string? _regexp = null)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                System.Text.RegularExpressions.Match? match = null;

                int index = 0;

                string tem_regexp_match = string.Empty;

                foreach (var i in RegExp.RegExpEmpty().Split(content))
                {

                    try
                    {
                        match = Regex.Match(i, @_regexp ?? @regexp);
                    }
                    catch
                    {
                        continue;
                    }
                    finally
                    {
                        if (match is not null)
                        {
                            if (match.Success)
                            {
                                foreach (var group in match.Groups)
                                {
                                    if (group is Group _Group && _Group.Value.IsAbsoluteValidValue())
                                    {
                                        index++;
                                        tem_regexp_match += $"第 {index} 条匹配: " + _Group.Value + "\r\n";
                                    }
                                }
                            }
                        }
                    }
                }
                if (tem_regexp_match.IsAbsoluteValidValue())
                {
                    regexpmc = tem_regexp_match;
                }
                else
                {
                    regexpmc = string.Empty;
                }
            });
        }
    }

    public class RegexpDescribe : Notify
    {
        private string _RegexHelpText =
            "*****基本字符*****Wrap" +
            ".Set匹配除换行符外的任何单个字符Wrap" +
            "\\nSet匹配换行符Wrap" +
            "\\tSet匹配制表符Wrap" +
            "\\rSet匹配回车符Wrap" +
            "\\Set匹配反斜杠本身Wrap" +
            "\\.Set匹配点号（.）本身Wrap" +
            "\\*Set匹配星号（*）本身Wrap" +

            "*****字符类*****Wrap" +
            "[T]Set匹配括号内的任意字符Wrap" +
            "[^T]Set匹配非方括号内的任意字符Wrap" +
            "[a-z]Set匹配指定范围内的任意字符Wrap" +
            "[0-9]Set匹配数字字符Wrap" +
            "[a-zA-Z]Set匹配字母字符Wrap" +
            "\\dSet匹配数字Wrap" +
            "\\DSet匹配非数字Wrap" +
            "\\wSet匹配单词字符[a-Z_]Wrap" +
            "\\WSet匹配非单词字符Wrap" +
            "\\sSet匹配空白字符Wrap" +
            "\\SSet匹配非空白字符Wrap" +

            "*****量词*****Wrap" +
            "*Set匹配前面的元素零次或多次Wrap" +
            "+Set匹配前面的元素一次或多次Wrap" +
            "?Set匹配前面的元素零次或一次Wrap" +
            "{n}Set匹配前面的元素N次Wrap" +
            "{n,}Set匹配前面的元素至少N次Wrap" +
            "{n,m}Set匹配前面的元素至少N次，最多M次Wrap" +

            "*****位置锚点*****Wrap" +
            "^Set匹配字符串的开始位置Wrap" +
            "$Set匹配字符串的结束位置Wrap" +
            "\\bSet匹配单词边界Wrap" +
            "\\BSet匹配非单词边界Wrap" +
            "\\ASet匹配字符串的绝对开始Wrap" +
            "\\ZSet匹配字符串的结束或结束前的换行Wrap" +

            "*****分组和捕获*****Wrap" +
            "(T)Set捕获分组，将匹配的内容保存到分组中Wrap" +
            "(?:T)Set非捕获分组，只分组不保存匹配内容Wrap" +
            "(?<name>T)Set命名捕获分组，给分组指定名称Wrap" +
            "|Set或操作符，匹配左边或右边的模式Wrap" +
            "\\1,\\2Set反向引用，引用前面捕获的分组Wrap" +

            "*****零宽断言*****Wrap" +
            "(?=T)Set正向肯定预查，后面必须跟着TWrap" +
            "(?!T)Set正向否定预查，后面不能跟着TWrap" +
            "(?<=T)Set反向肯定预查，前面必须是TWrap" +
            "(?<!T)Set反向否定预查，前面不能是TWrap" +

            "*****模式修饰符*****Wrap" +
            "(?i)Set忽略大小写匹配Wrap" +
            "(?m)Set多行模式，^和$匹配每行的开始和结束Wrap" +
            "(?s)Set单行模式，.匹配包括换行符在内的所有字符Wrap" +
            "(?x)Set忽略模式中的空白和注释";

        public RegexpDescribe()
        {
            InitExplainText();
        }

        private void InitExplainText()
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                StringBuilder Substring = new();

                foreach (var subcript in _RegexHelpText.Split("Wrap"))
                {
                    string[] rowinfo = subcript.Split("Set");

                    if (rowinfo.Length == 2)
                    {
                        string mainbody = rowinfo.ElementAt(0);
                        string explain = rowinfo.ElementAt(1);
                        Substring.Append(mainbody.SubjoinString(7, 1) + explain + "\r\n");
                    }
                    else if (rowinfo.Length == 1)
                    {
                        string explain = rowinfo.ElementAt(0);
                        Substring.Append("\r\n\r\n" + explain.SubjoinString(25, 0) + "\r\n\r\n");
                    }
                }
                RegexHelpText = Substring.ToString();
            });
        }

        public string RegexHelpText 
        { 
            set
            {
                _RegexHelpText = value;
                propertyChangeSend(nameof(RegexHelpText));
            }
            get
            {
                return _RegexHelpText;
            }
        }
    }
}
